﻿using Server.Business;
using Server.Business.proto;
using Server.Database;
using Server.Resource;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;

namespace Server.TCP
{
    public class ProdFactory
    {
        private static Dictionary<string, PropertyInfo> _propertyCache;

        private static IList<MappingColumn> _columns;
        private static IList<ImageColumn> _imageColumns;
        private DirectoryInfo _forder;


        static ProdFactory()
        {
            _propertyCache = new Dictionary<string, PropertyInfo>();
            foreach (PropertyInfo pi in typeof(ProdDB).GetProperties())
            {
                _propertyCache[pi.Name] = pi;
            }

            ResourceProvider rp = new ResourceProvider();
            _columns = new List<MappingColumn>()
            {
                new PrimitiveTypeColumn() { Column = "产品系列", Property = "ProdSeries", Index=5 },
                new RefColumn() {  Column = "产品分类", Property = "ProdClass", Index=6, Items = rp.ProductTypes },
                new RefColumn() {  Column = "使用场所", Property = "ProdPlace", Index=7, Items = rp.UseArea },
                new PrimitiveTypeColumn() {  Column = "规格型号", Property = "ProdVersion", Index=8 },
                new PrimitiveTypeColumn() {  Column = "产品品牌", Property = "ProdLabel", Index=9 },
                new RefColumn() {  Column = "产地", Property = "ProdOrgin", Index=12, Items = rp.Orgin },

                new PrimitiveTypeColumn() {  Column = "材质说明", Property = "PhyMaterial", Index=13 },
                new PrimitiveTypeColumn() {  Column = "外观颜色", Property = "PhyColor", Index=14 },
                new PrimitiveTypeColumn() {  Column = "外形尺寸", Property = "PhySize", Index=15 },
                new PrimitiveTypeColumn() {  Column = "防护等级", Property = "PhyDefend", Index=16},
                new RefColumn() {  Column = "防撞击等级", Property = "PhyImpact", Index=18, Items = rp.ImpactType },
                new PrimitiveTypeColumn() {  Column = "产品重量", Property = "PhyWeight", Index=19 },

                new RefColumn() {  Column = "配光说明", Property = "OptExplain", Index=21, Items = rp.LightingExplain },
                new PrimitiveTypeColumn() {  Column = "光束角", Property = "OptAngle", Index=22 },
                new PrimitiveTypeColumn() {  Column = "灯具效率", Property = "OptEff", Index=23 },

                new PrimitiveTypeColumn() {  Column = "防触电等级", Property = "EleShock", Index=24 },
                new RefColumn() {  Column = "工作电压", Property = "EleVoltage", Index=25, Items = rp.WorkVoltage },
                new PrimitiveTypeColumn() {  Column = "电器类型", Property = "EleType", Index=26 },
                new PrimitiveTypeColumn() {  Column = "电器功耗", Property = "ElePower", Index=27 },
                new PrimitiveTypeColumn() {  Column = "光源功率", Property = "EleLgtPower", Index=28 },
                new PrimitiveTypeColumn() {  Column = "整灯功耗", Property = "EleAllPower", Index=29 },
                new RefColumn() {  Column = "控制方式", Property = "EleCtlType", Index=31, Items = rp.ControlType },

                new RefColumn() {  Column = "光源种类", Property = "AdpClass", Index=32, Items = rp.LightingType },
                new PrimitiveTypeColumn() {  Column = "光源型号", Property = "AdpVersion", Index=34 },
                new PrimitiveTypeColumn() {  Column = "色温或颜色", Property = "AdpColor", Index=35 },
                new PrimitiveTypeColumn() {  Column = "显色性CRI", Property = "AdpCri", Index=36 },
                new PrimitiveTypeColumn() {  Column = "光输出", Property = "AdpOutput", Index=37 },
                new PrimitiveTypeColumn() {  Column = "插脚形式", Property = "AdpPins", Index=38 },

                new PrimitiveTypeColumn() {  Column = "可选配件", Property = "ProjParts", Index=41 },
                new RefColumn() {  Column = "安装方式", Property = "ProjSetup", Index=42, Items = rp.SetupType },
                new PrimitiveTypeColumn() {  Column = "安装尺寸", Property = "ProjSize", Index=43 },
                new PrimitiveTypeColumn() {  Column = "认证及检测报告", Property = "ProjReport", Index=48 },
                new PrimitiveTypeColumn() {  Column = "备注", Property = "ProjBaikup", Index=49 },

                new PrimitiveTypeColumn() {  Column = "参考进价", Property = "BusIn", Index=55 },
                new PrimitiveTypeColumn() {  Column = "市场参考价", Property = "BusMarket", Index=56 },
                new PrimitiveTypeColumn() {  Column = "参考售价", Property = "BusOut", Index=57 },
                new PrimitiveTypeColumn() {  Column = "参考货期", Property = "BusExpires", Index=58 }
            };

            _imageColumns = new List<ImageColumn>()
            {
                new ImageColumn() 
                {  
                    Index=59, 
                    Column = "图片(外观)", 
                    Property = "PicFacade", 
                    ZoomLevels = new int[] { ProdDB.Zoom70, ProdDB.Zoom100, ProdDB.Zoom150 }
                },
                new ImageColumn() {  Index=60, Column = "图片(尺寸)", Property = "PicSize", ZoomLevels = new int[] { ProdDB.Zoom100 } },
                new ImageColumn() {  Index=61, Column = "图片(配光1)", Property = "PicGrading", ZoomLevels = new int[] { ProdDB.Zoom100 } },
                new ImageColumn() {  Index=62, Column = "图片(实景)", Property = "PicLive", ZoomLevels = new int[] { ProdDB.Zoom100 } }
            };
        }

        public IList<ProdDB> Create(byte[] packages)
        {
            string newForder = Path.Combine(ServerConfig.Singleton.ImgRoot, DateTime.Now.ToString("yyyyMMddHHmmss"));
            _forder = Directory.CreateDirectory(newForder);
            foreach (int imageLevel in new int[] { ProdDB.Zoom70, ProdDB.Zoom100, ProdDB.Zoom150 })
            {
                Directory.CreateDirectory(Path.Combine(newForder, imageLevel.ToString()));
            }

            WorkbookParser parser = new WorkbookParser(packages);
            WorkbookModel model = parser.Parse();

            SLExcelReader reader = new SLExcelReader();
            SLExcelData excelData = reader.ReadExcel(model.ExcelFile.Stream);

            List<ProdDB> list = new List<ProdDB>();
            int index = 0;
            foreach (List<string> data in excelData.DataRows)
            {
                index++;
                ProdDB prodDB = Create(data, string.Format("{0}|{1}|", excelData.SheetName, index + 2), model);
                if (prodDB != null)
                    list.Add(prodDB);
            }
            return list;
        }

        private byte[] BmpToPNG(byte[] stream)
        {
            Image img = Image.FromStream(new MemoryStream(stream));
            byte[] arr = null;
            using (MemoryStream ms = new MemoryStream())
            {
                img.Save(ms, ImageFormat.Png);
                arr = ms.ToArray();
            }

            return arr;
        }

        private ProdDB Create(IList<string> data, string prefixKey, IImageProvider provider)
        {
            ProdDB instance = (ProdDB)Activator.CreateInstance(typeof(ProdDB));

            foreach (MappingColumn column in _columns)
            {
                try
                {
                    string value = data[column.Index];
                    if (string.IsNullOrEmpty(value))
                        continue;

                    value = value
                        .Trim()
                        .Replace("K", string.Empty)
                        .Replace("k", string.Empty)
                        .Replace("W", string.Empty)
                        .Replace("w", string.Empty)
                        .Replace("°", string.Empty);

                    column.SetValue(_propertyCache[column.Property], instance, value);
                }
                catch (Exception ex)
                {
                }
            }

            if (instance.ProdClass == 0)
                return null;

            instance.PicFolder = _forder.Name;
            foreach (ImageColumn column in _imageColumns)
            {
                try
                {


                    string imageKey = string.Format("{0}{1}", prefixKey, column.Index + 1);
                    ImageFile imageFile = provider.GetImageFileByKey(imageKey);
                    if (imageFile != null)
                    {
                        column.ImageFolder = _forder.FullName;
                        column.ImageFile = imageFile;
                        column.SetValue(_propertyCache[column.Property], instance, null);
                    }
                }
                catch (Exception ex)
                {
                }
            }

            return (ProdDB)instance;
        }
    }
}
